package com.example.demo.domain.dto;

import com.example.demo.constant.CommonConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.slf4j.MDC;
import org.springframework.util.StringUtils;

import java.io.Serializable;

/**
 * 统一返回json对象
 *
 * @author renliang
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> implements Serializable {

    private Integer code;
    private String msg;
    private T data;
    private String traceId;
    private Long timestamp = System.currentTimeMillis();

    public static <T> Result<T> success() {
        return of(null, ResultCode.SUCCESS.getMsg(), ResultCode.SUCCESS.getCode(), null);
    }

    public static <T> Result<T> success(T data, String msg) {
        return of(data, msg, ResultCode.SUCCESS.getCode(), null);
    }

    public static <T> Result<T> success(T data) {
        return of(data, ResultCode.SUCCESS.getMsg(), ResultCode.SUCCESS.getCode(), null);
    }

    public static <T> Result<T> success(T data, String msg, int code, String traceId) {
        return of(data, msg, code, traceId);
    }

    public static <T> Result<T> error(T data, String msg, ResultCode code, String traceId) {
        code = code == null ? ResultCode.ERROR : code;
        return of(data, StringUtils.hasText(msg) ? msg : code.getMsg(), code.getCode(), traceId);
    }

    public static <T> Result<T> error(String msg, String traceId) {

        return of(null, StringUtils.hasText(msg) ? msg : ResultCode.ERROR.getMsg(), ResultCode.ERROR.getCode(), traceId);
    }

    public static <T> Result<T> error(String msg) {
        return of(null, StringUtils.hasText(msg) ? msg : ResultCode.ERROR.getMsg(), ResultCode.ERROR.getCode(), MDC.get(CommonConstant.LOG_TRACE_ID));
    }

    public static <T> Result<T> error(ResultCode code, String msg, String traceId) {
        code = code == null ? ResultCode.ERROR : code;
        return of(null, StringUtils.hasText(msg) ? msg : code.getMsg(), code.getCode(), traceId);
    }

    public static <T> Result<T> error(T data, ResultCode code) {
        code = code == null ? ResultCode.ERROR : code;
        return of(data, code.getMsg(), code.getCode(), null);
    }

    public static <T> Result<T> error(ResultCode code, String msg) {
        code = code == null ? ResultCode.ERROR : code;
        return of(null, msg, code.getCode(), null);
    }

    public static <T> Result<T> error(ResultCode code) {
        code = code == null ? ResultCode.ERROR : code;
        return of(null, code.getMsg(), code.getCode(), null);
    }

    public static <T> Result<T> warn(ResultCode code, String msg) {
        code = code == null ? ResultCode.WARN : code;
        return of(null, msg, code.getCode(), null);
    }

    public static <T> Result<T> warn(ResultCode code) {
        code = code == null ? ResultCode.WARN : code;
        return of(null, code.getMsg(), code.getCode(), null);
    }

    public static <T> Result<T> warn(ResultCode code, String msg, String traceId) {
        code = code == null ? ResultCode.WARN : code;
        return of(null, StringUtils.hasText(msg) ? msg : code.getMsg(), code.getCode(), traceId);
    }

    public static <T> Result<T> warn(T data, ResultCode code) {
        code = code == null ? ResultCode.WARN : code;
        return of(data, code.getMsg(), code.getCode(), null);
    }


    public static <T> Result<T> warn(T data, String msg, ResultCode code, String traceId) {
        code = code == null ? ResultCode.WARN : code;
        return of(data, StringUtils.hasText(msg) ? msg : code.getMsg(), code.getCode(), traceId);
    }

    public static <T> Result<T> warn(String msg, String traceId) {

        return of(null, StringUtils.hasText(msg) ? msg : ResultCode.WARN.getMsg(), ResultCode.WARN.getCode(), traceId);
    }

    public static <T> Result<T> warn(String msg) {
        return of(null, StringUtils.hasText(msg) ? msg : ResultCode.WARN.getMsg(), ResultCode.WARN.getCode(), MDC.get(CommonConstant.LOG_TRACE_ID));
    }


    public static <T> Result<T> of(T data, String msg, Integer code, String traceId) {
        traceId = StringUtils.hasText(traceId) ? traceId : MDC.get(CommonConstant.LOG_TRACE_ID);
        return new Result(code, msg, data, traceId, System.currentTimeMillis());
    }
}
